package com.example.commonmistak.reflection;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 泛型和继承
 * @author xiongwei
 * @date 2022/1/7 10:01
 */
public class GenericsAndInheritanceDemo {

    public static void main(String[] args) {
        //setValue 方法调用了两次
        wrong();
        System.out.println("======");
        right();
    }

    public static void wrong() {
        Child child = new Child();

        Arrays.stream(child.getClass().getMethods())
                .filter(method -> method.getName().equals("setValue"))
                .forEach(method -> {
                    try {
                        method.invoke(child, "test");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
        System.out.println(child.toString());
    }

    public static void right() {
        Child child = new Child();

        Arrays.stream(child.getClass().getMethods())
                // isBridge 判断是否桥接方法
                .filter(method -> method.getName().equals("setValue") && !method.isBridge())
                .forEach(method -> {
                    try {
                        method.invoke(child, "test");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
        System.out.println(child.toString());
    }
}

class Parent<T> {

    AtomicInteger updateCount = new AtomicInteger();

    private T value;

    public void setValue(T value) {
        System.out.println("Parent setValue called");
        this.value = value;
        updateCount.incrementAndGet();
    }

    @Override
    public String toString() {
        return "updateCount=" + updateCount +
                ", value=" + value;
    }
}

class Child extends Parent<String> {

    @Override
    public void setValue(String value) {
        System.out.println("Child setValue called");
        super.setValue(value);
    }
    
}